﻿// // --------------------------------------------------------------------------------------------------------------------
// // <copyright file="SPTDocumentLibraryPage.cs" company="Collaboris">
// //   Copyright Collaboris
// // </copyright>
// // <summary>
// //   
// // </summary>
// // --------------------------------------------------------------------------------------------------------------------

namespace Collaboris.ShareTest.SharePoint2010.PageObjects.AppPages
{
    #region

    using System.Collections.Generic;
    using System.Collections.ObjectModel;

    using Collaboris.ShareTest.Core;
    using Collaboris.ShareTest.SharePoint2010.ControlObjects;

    using OpenQA.Selenium;
    using OpenQA.Selenium.Remote;

    using Spring.Objects;

    #endregion

    /// <summary>
    /// 	The Doc Library Page
    /// </summary>
    /// <typeparam name = "TDocumentItem">
    /// </typeparam>
    public class SPTDocumentLibraryPage<TDocumentItem> : SPTPageObjectBase
        where TDocumentItem : SPTDocumentItem, new()
    {
        #region Constructors and Destructors

        /// <summary>
        /// 	Initializes a new instance of the <see cref = "SPTDocumentLibraryPage"></see>
        /// 	class.
        /// </summary>
        /// <param name = "driver">
        /// 	The Driver.
        /// </param>
        /// <param name = "fullUrl">
        /// 	The fullUrl.
        /// </param>
        public SPTDocumentLibraryPage(RemoteWebDriver driver, string fullUrl)
            : base(driver, fullUrl)
        {
        }

        public SPTDocumentLibraryPage(RemoteWebDriver driver, string fullUrl, string verifyElementOnLoad)
            : base(driver, fullUrl, verifyElementOnLoad)
        {
        }

        public SPTDocumentLibraryPage(
            RemoteWebDriver driver, string fullUrl, string verifyElementOnLoad, string loginFileName)
            : base(driver, fullUrl, verifyElementOnLoad, loginFileName)
        {
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 	The edit and save document properties.
        /// </summary>
        /// <param name = "exactDocumentTitle">
        /// 	The exact document title.
        /// </param>
        public void EditAndSaveDocumentProperties(string exactDocumentTitle)
        {
            //By aRef = By.XPath("//a[contains(text(), 'Alcohol and drug abuse policy')]");
            //webDriver.Focus(webDriver.FindElement(aRef));

            //By documentContextMenu =
            //    By.XPath(
            //        "//a[contains(text(), 'Alcohol and drug abuse policy')]/parent::div/parent::td/div/a[@title='Open Menu']");
            //webDriver.Focus(webDriver.FindElement(documentContextMenu));
            //webDriver.ClickWithWait(documentContextMenu);
        }

        /// <summary>
        /// 	The get document column names.
        /// </summary>
        /// <returns>
        /// 	A list of Column names for the library (in the order on screen)
        /// </returns>
        public List<string> GetDocumentColumnNames()
        {
            Logger.LogMessage("Getting Document Column Names");
            List<string> columnNames;
            this.GetDocuments("onetidDoclibViewTbl0", out columnNames, true);
            return columnNames;
        }

        /// <summary>
        /// 	The get documents.
        /// </summary>
        /// <returns>
        /// 	All the documents on the first page
        /// </returns>
        public List<TDocumentItem> GetDocuments()
        {
            Logger.LogMessage("Getting Documents");
            List<string> columnNames;
            return this.GetDocuments("onetidDoclibViewTbl0", out columnNames, false);
        }

        /// <summary>
        /// 	Gets all of the documents on a page.
        /// </summary>
        /// <param name = "tableId">
        /// 	The table Id.
        /// </param>
        /// <param name = "columnNames">
        /// 	The column Names.
        /// </param>
        /// <param name = "headingsOnly">
        /// 	The headings Only.
        /// </param>
        /// <returns>
        /// 	All the documents on the first page
        /// </returns>
        public List<TDocumentItem> GetDocuments(string tableId, out List<string> columnNames, bool headingsOnly)
        {
            Logger.LogMessage("Get Documents");
            IWebElement documentsTable = this.webDriver.FindElement(By.Id(tableId));
            ReadOnlyCollection<IWebElement> elements =
                documentsTable.FindElements(By.XPath("id('" + tableId + "')/tbody/tr"));
            int rowNumber = 0;
            columnNames = null;
            List<TDocumentItem> documents = new List<TDocumentItem>();

            foreach (IWebElement tableRowElements in elements)
            {
                if (rowNumber == 0)
                {
                    columnNames = GetHeadings(tableRowElements);
                    if (headingsOnly)
                    {
                        return null;
                    }
                }
                else
                {
                    TDocumentItem document = this.GetDocFromRow(rowNumber, tableRowElements, columnNames);
                    documents.Add(document);
                }

                rowNumber++;
            }

            return documents;
        }

        #endregion

        #region Methods

        /// <summary>
        /// 	The get headings.
        /// </summary>
        /// <param name = "tableRowElements">
        /// 	The table row elements.
        /// </param>
        /// <returns>
        /// 	Gets the headings from the first rown
        /// </returns>
        private static List<string> GetHeadings(IWebElement tableRowElements)
        {
            ReadOnlyCollection<IWebElement> tableColElements = tableRowElements.FindElements(By.XPath("th"));
            int colNumber = 0;

            List<string> columnNames = new List<string>();

            foreach (IWebElement colElement in tableColElements)
            {
                try
                {
                    string columnName = colElement.FindElement(By.TagName("div")).GetAttribute("name");

                    if (string.IsNullOrEmpty(columnName))
                    {
                        columnName = "No-Name";
                    }

                    columnNames.Add(columnName);
                }
                catch
                {
                    columnNames.Add("No-Name");
                }

                colNumber++;
            }

            return columnNames;
        }

        private static void TrySetProperty(
            string columnName, string columnText, int colNumber, ObjectWrapper wrappedDoc)
        {
            try
            {
                wrappedDoc.SetPropertyValue(columnName, columnText);
            }
            catch
            {
            }
        }

        /// <summary>
        /// 	The get doc from row.
        /// </summary>
        /// <param name = "rowNumber">
        /// 	The row number.
        /// </param>
        /// <param name = "tableRowElements">
        /// 	The table row elements.
        /// </param>
        /// <param name = "columnNames">
        /// 	The column names.
        /// </param>
        /// <returns>
        /// 	An SPTDocumentItem based on the rownumber in the grid
        /// </returns>
        private TDocumentItem GetDocFromRow(int rowNumber, IWebElement tableRowElements, List<string> columnNames)
        {
            ReadOnlyCollection<IWebElement> tableColElements = tableRowElements.FindElements(By.XPath("td"));
            int colNumber = 0;

            TDocumentItem document = new TDocumentItem();
            document.WebDriver = this.webDriver;
            ObjectWrapper wrappedDoc = new ObjectWrapper(document);
            foreach (IWebElement colElement in tableColElements)
            {
                string columnText = null;
                if (string.IsNullOrEmpty(colElement.Text))
                {
                    columnText = colElement.GetAttribute("innerHTML");
                }
                else
                {
                    columnText = colElement.Text;
                }

                Logger.LogMessage("row : " + rowNumber + " col: " + colNumber + "Text : " + columnText);

                if (columnNames[colNumber] != "No-Name")
                {
                    TrySetProperty(columnNames[colNumber], columnText, colNumber, wrappedDoc);
                }

                TrySetProperty("Position", columnText, colNumber, wrappedDoc);

                colNumber++;
            }

            return document;
        }

        #endregion
    }

    /// <summary>
    /// 	This class is used to provide parsing hints 
    /// 	so that things like name and extraction can
    /// 	be set.
    /// </summary>
    public class ColumnParser
    {
        #region Public Properties

        /// <summary>
        /// 	Gets or sets Name.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 	Gets or sets XPath.
        /// </summary>
        public string XPath { get; set; }

        #endregion
    }
}